Skip to content

Adding uv to the Github CI and requirements to pyproject#452

Open
emlynsg wants to merge 25 commits intomasterfrom
uv-nox
Open

Adding uv to the Github CI and requirements to pyproject#452
emlynsg wants to merge 25 commits intomasterfrom
uv-nox

Conversation

@emlynsg
Copy link
Copy Markdown
Contributor

@emlynsg emlynsg commented Feb 26, 2026

This PR changes Graphix to use uv instead of pip in the nox routine for CI tests.
To adhere to the requirements of uv, it also includes a uv.lock file locking dependencies for CI reproducibility, and has merged requirements into the pyproject.toml file in line with PEP best practice (https://packaging.python.org/en/latest/specifications/pyproject-toml/). A new Github action has been created to check the uv lockfile matches the pyproject.

The installation process remains the same with this change - either pip install -e . or uv sync (the latter preferred for reproducibility and speed). See changes to the CONTRIBUTING.md and README.md for more details.

This PR also turns off ruff preview mode, to keep linting more stable, alongside changing the dependabot to use uv. Changes to Graphix internal files are due to linting changes introduced by this reversion.

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.98%. Comparing base (aa0d407) to head (4db8fef).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #452   +/-   ##
=======================================
  Coverage   88.98%   88.98%           
=======================================
  Files          44       44           
  Lines        6545     6545           
=======================================
  Hits         5824     5824           
  Misses        721      721           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Emlyn Graham and others added 8 commits February 26, 2026 19:41
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@emlynsg emlynsg linked an issue Feb 27, 2026 that may be closed by this pull request
@emlynsg emlynsg marked this pull request as ready for review March 10, 2026 13:48
emlynsg and others added 3 commits March 10, 2026 14:51
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Collaborator

@thierry-martinez thierry-martinez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice! Thanks. I have some minor remarks. I also question whether we should version uv.lock, since it appears to be a large generated file likely to cause merge conflicts. I'd prefer to stick with our policy of specifying version constraints in pyproject.toml on a case-by-case basis.


project = "graphix"
copyright = "2022, Team Graphix"
copyright = "2026, Team Graphix"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could put a year range: 2022-2026.

Comment on lines +31 to +32
uv run ruff check --select I --fix .
uv run ruff format .
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add an equivalent to the code coverage command from before:

uv run pytest --cov=./graphix --cov-report=xml --cov-report=term --doctest-modules


- name: Run Ruff Linter
run: ruff check --output-format=github
run: uv run --extra dev ruff check --output-format=github
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously, we installed just ruff (constrained by requirements-dev.txt) instead of all dev dependencies: pip install ruff -c requirements-dev.txt

With uv, the equivalent is:

Suggested change
run: uv run --extra dev ruff check --output-format=github
run: uv run --with ruff ruff check --output-format=github


- name: Run Ruff Formatter Check
run: ruff format --check
run: uv run --extra dev ruff format --check No newline at end of file
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
run: uv run --extra dev ruff format --check
run: uv run --with ruff ruff format --check


git clone https://github.com/TeamGraphix/graphix.git
cd graphix
uv sync --extra dev --extra extra
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add the step pip install uv, since uv is not part of the standard Python distribution.

git clone git@github.com:TeamGraphix/graphix.git
cd graphix
pip install -e .[dev]
uv sync --extra dev --extra extra
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend to add pip install uv here as well.

CONTRIBUTING.md Outdated
```bash
pip install .[dev]
pytest --cov=./graphix --cov-report=xml --cov-report=term
uv run ruff check --select I --fix .
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, the rule I is already selected in pyproject.toml.

Suggested change
uv run ruff check --select I --fix .
uv run ruff check --fix .

I would add a point about test coverage: uv run pytest --cov=./graphix --cov-report=xml --cov-report=term --doctest-modules

CONTRIBUTING.md Outdated

```bash
pip install -e . --config-settings editable_mode=strict
pip install . --config-settings editable_mode=strict
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The --config-settings editable_mode=strict flag is only useful with -e (editable installs); it ensures type-checking works correctly with editable packages. I don't know if uv offers an equivalent setting for installing packages as editable while preserving type-checking support.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The command I've changed it to seems to work. We can also put this in the pyproject.toml to enforce strict editable mode always, but not sure if that's what we want?

pyproject.toml Outdated
"pytest-mpl",
"qiskit>=1.0",
"qiskit_qasm3_import",
"qiskit-aer; python_version < '3.14'",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Python version constraint can be removed (see #462).

Suggested change
"qiskit-aer; python_version < '3.14'",
"qiskit-aer",


- name: Run Ruff Linter
run: ruff check --output-format=github
run: uv run --with ruff ruff check --output-format=github
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[:art: text-formatter] reported by reviewdog 🐶

Suggested change
run: uv run --with ruff ruff check --output-format=github
run: uv run --with ruff ruff check --output-format=github


- name: Run Ruff Formatter Check
run: ruff format --check
run: uv run --with ruff ruff format --check No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[:art: text-formatter] reported by reviewdog 🐶

Suggested change
run: uv run --with ruff ruff format --check
run: uv run --with ruff ruff format --check


These settings enable the linter, format the code on save and turn on basic
static type checking through the Pylance extension.
static type checking through the Pylance extension. No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[:art: text-formatter] reported by reviewdog 🐶

Suggested change
static type checking through the Pylance extension.
static type checking through the Pylance extension.

Copy link
Copy Markdown
Contributor

@matulni matulni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!
Here are some comments


We recommend to [fork the repository](https://docs.github.com/en/get-started/quickstart/fork-a-repo) before working on new features, whether that being an existing issue or your own idea.
Once created, you'll need to clone the repository, and you can follow below to set up the environment. You may want to set up virtual environment, such as `conda env` or `pipenv` before setting up the environment.
Once created, you'll need to clone the repository, and you can follow below to set up the environment. We recommend you use a virtual environment like `uv`, but you may prefer to use `conda env` or `pipenv`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Once created, you'll need to clone the repository, and you can follow below to set up the environment. We recommend you use a virtual environment like `uv`, but you may prefer to use `conda env` or `pipenv`.
Once created, you'll need to clone the repository, and you can follow below to set up the environment. We recommend you use a project manager like `uv`, but you may prefer to manage your own virtual environment with `conda env` or `pipenv`.

### Local checks

To replicate the CI pipeline locally, install `nox` and run the tests:
You can also run the full CI suite locally:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can also run the full CI suite locally:
You can also run the full CI test suite locally:

My understanding is that our nox file doesn't do anything about typecheckers or linters.

ruff format .
uv run ruff check .
uv run ruff format --check .
uv run mypy
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
uv run mypy
uv run mypy
uv run pyright

Once created, you'll need to clone the repository, and you can follow below to set up the environment. We recommend you use a virtual environment like `uv`, but you may prefer to use `conda env` or `pipenv`.

```bash
git clone git@github.com:<username>/graphix.git
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was consistent with the recommendation of forking the repo above.

Comment on lines +28 to +37
dependencies = [
"matplotlib",
"networkx",
"numpy>=2",
"opt_einsum",
"quimb",
"scipy",
"sympy",
"typing_extensions",
]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we take the opportunity of this PR to pin all dependencies ?
I believe that this will yield safer and more stable code, not sure if dependabot takes care of updating them...

Suggested change
dependencies = [
"matplotlib",
"networkx",
"numpy>=2",
"opt_einsum",
"quimb",
"scipy",
"sympy",
"typing_extensions",
]
dependencies = [
"matplotlib==3.10.8",
"networkx==3.6.1",
"numpy==2.4.4",
"quimb==1.13.0",
"scipy==1.17.1",
"sympy==1.14.0",
"typing_extensions==4.15.0",
]

Also, I believe that opt_einsum is not used in the codebase (tests pass without), but could someone else double check please?

Comment on lines +34 to +35
enable-cache: true
cache-dependency-glob: "pyproject.toml"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's suggested to pin the uv version as well

Suggested change
enable-cache: true
cache-dependency-glob: "pyproject.toml"
version: "0.11.3" # Install a specific version of uv.
enable-cache: true
cache-dependency-glob: "pyproject.toml"

Comment on lines +37 to +38
- name: "Set up Python ${{ matrix.python }}"
run: uv python install ${{ matrix.python }}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a difference between this and setting

with:
          python-version: ${{ matrix.python }}

in the previous action as shown in the docs ?

if TYPE_CHECKING:
from collections.abc import Callable

nox.options.default_venv_backend = "uv"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep the default as a fallback

Suggested change
nox.options.default_venv_backend = "uv"
nox.options.default_venv_backend = "uv|virtualenv"


- run: nox --python ${{ matrix.python }}
- name: Run nox
run: uvx nox -db uv --python ${{ matrix.python }}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two questions:

  1. If I understood correctly this comment, it seems that nox installs the appropriate Python version. Does this mean that we can skip the uv python install ... above ?
  2. Is there a reason why we are doing uvx nox instead of uv run nox ?

Comment on lines +21 to +24
- name: Setup uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments in ci.yml about versions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace nox with uv in CI

3 participants